/* Includes ------------------------------------------------------------------*/
#include "MY_I2C_DRV.h"
#include "M117_MTS01_I2C.h"
/* Definition of GPIOI2C constants */
#define GPIOI2C_ACK  				((uint8_t)1)
#define GPIOI2C_NACK 				((uint8_t)0)
#define I2CWRITE_MASK  			((uint8_t)0xFE)
#define I2CREAD_MASK   			((uint8_t)0x01)

/* Exported functions ---------------------------------------------------------*/

void GPIOI2C_Bus_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_AHBPeriphClockCmd(I2C_SCL_BUSCLK, ENABLE);
	RCC_AHBPeriphClockCmd(I2C_SDA_BUSCLK, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	
	GPIO_Init(I2C_SCL_PORT, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = I2C_SDA_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIO_Init(I2C_SDA_PORT, &GPIO_InitStructure);
	
	i2c_set_sda();
	i2c_set_scl() ;
}

/**-----------------------------------------------------------------------
  * @brief  无参指令传递函数（针对仅发送指令，如测温转换）
  * @param  DeviceAddr：地址  *Buff：指令数组  Size：发送数据总长度
  * @retval 是否传输成功
-------------------------------------------------------------------------*/
uint8_t M117_MTS01_Transmit(uint8_t DeviceAddr, uint8_t* Buff, uint8_t Size)
{
	uint8_t i, ret = GPIOI2C_XFER_LASTACK;

	I2C_Start();
	if (I2C_master_write((DeviceAddr << 1) & I2CWRITE_MASK) == GPIOI2C_NACK)
	{
		I2C_Stop();
		return GPIOI2C_XFER_ADDRNACK;
	}

	for (i = 0; i < Size; i++)
	{
		if (I2C_master_write((*Buff++)) == GPIOI2C_NACK)
		{
			if (i < (Size - 1))
			{
				ret = GPIOI2C_XFER_ABORTNACK;
				break;
			}
			else
			{
				ret = GPIOI2C_XFER_LASTNACK;
			}
		}
	}
	I2C_Stop();
	return ret;
}

/**-----------------------------------------------------------------------
  * @brief  温度数据接收函数
  * @param  DeviceAddr：地址  *Buff：数据存储数组  Size：发送数据总长度
  * @retval 是否传输成功
-------------------------------------------------------------------------*/
uint8_t M117_MTS01_Receive(uint8_t DeviceAddr, uint8_t* Buff, uint8_t Size)
{
	uint8_t i;

	I2C_Start();
	if (I2C_master_write((DeviceAddr << 1) | I2CREAD_MASK) == GPIOI2C_NACK)
	{
		I2C_Stop();
		return GPIOI2C_XFER_ADDRNACK;
	}

	for (i = 0; i < (Size - 1); i++)
	{
		(*Buff++) = I2C_master_read(GPIOI2C_ACK);
	}

	(*Buff) = I2C_master_read(GPIOI2C_NACK);

	I2C_Stop();

	return GPIOI2C_XFER_LASTNACK;
}

/**-----------------------------------------------------------------------
  * @brief  有参指令传递函数（针对某些指令后需要写入配置参数类型，如配置量程）
  * @param  DeviceAddr:地址 cmd:传达的指令 *pdata:随指令传递的参数 Size:发送数据总长度
  * @retval 是否传输成功
-------------------------------------------------------------------------*/
uint8_t M117_MTS01_Cmd_Write(uint8_t DeviceAddr, uint16_t cmd, uint8_t* pData, uint8_t Size)
{
	uint8_t i, ret = GPIOI2C_XFER_LASTACK;

	I2C_Start();
	if (I2C_master_write((DeviceAddr << 1) & I2CWRITE_MASK) == GPIOI2C_NACK)
	{
		I2C_Stop();
		return GPIOI2C_XFER_ADDRNACK;
	}

	if (I2C_master_write((uint8_t)(cmd >> 8)) == GPIOI2C_NACK)
	{
		I2C_Stop();
		return GPIOI2C_XFER_ABORTNACK;
	}
	if (I2C_master_write((uint8_t)(cmd)) == GPIOI2C_NACK)
	{
		I2C_Stop();
		return GPIOI2C_XFER_ABORTNACK;
	}

	for (i = 0; i < Size; i++)
	{
		if (I2C_master_write((*pData++)) == GPIOI2C_NACK)
		{
			if (i < (Size - 1)) { ret = GPIOI2C_XFER_ABORTNACK; break; }
			else { ret = GPIOI2C_XFER_LASTNACK; }
		}
	}

	I2C_Stop();
	return ret;
}

/**-----------------------------------------------------------------------
  * @brief  寄存器数据读取函数（针对某些指令后需要读取数据）
  * @param  DeviceAddr：地址  Cmd：待发送读取指令 *pdata:读取到的数据 Size：读取的数据长度
  * @retval 是否传输成功
-------------------------------------------------------------------------*/
uint8_t M117_MTS01_Cmd_Read(uint8_t DeviceAddr, uint16_t Cmd, uint8_t* pData, uint8_t Size)
{
	uint8_t i;

	I2C_Start();
	if (I2C_master_write((DeviceAddr << 1) & I2CWRITE_MASK) == GPIOI2C_NACK)
	{
		I2C_Stop();
		return GPIOI2C_XFER_ADDRNACK;
	}

	if (I2C_master_write((uint8_t)(Cmd >> 8)) == GPIOI2C_NACK)
	{
		I2C_Stop();

		return GPIOI2C_XFER_ABORTNACK;
	}

	if (I2C_master_write((uint8_t)(Cmd)) == GPIOI2C_NACK)
	{
		I2C_Stop();

		return GPIOI2C_XFER_ABORTNACK;
	}

	I2C_reStart();

	if (I2C_master_write((DeviceAddr << 1) | I2CREAD_MASK) == GPIOI2C_NACK)
	{
		I2C_Stop();

		return GPIOI2C_XFER_ABORTNACK;
	}

	for (i = 0; i < (Size - 1); i++)
	{
		(*pData++) = I2C_master_read(GPIOI2C_ACK);
	}

	(*pData) = I2C_master_read(GPIOI2C_NACK);

	I2C_Stop();

	return GPIOI2C_XFER_LASTNACK;
}

/**-----------------------------------------------------------------------
  * @brief  唤醒芯片
  * @param  无
  * @retval 无
-------------------------------------------------------------------------*/
void Quick_wakeup(void)
{
	i2c_set_scl();
	i2c_clear_sda();

	MY_DELAY_US(50);
	i2c_set_sda();

	MY_DELAY_US(10);
	i2c_clear_scl();

	MY_DELAY_US(20);
	i2c_clear_sda();

	MY_DELAY_US(25);
	i2c_set_scl();

	MY_DELAY_US(10);
	i2c_set_sda();
	MY_DELAY_US(15);
}

/**-----------------------------------------------------------------------
  * @brief  主机向芯片发送start指令
  * @param  无
  * @retval start标志位
-------------------------------------------------------------------------*/
void I2C_Start(void)
{
	Quick_wakeup();
	Quick_wakeup();
	Quick_wakeup();
	Quick_wakeup();
	Quick_wakeup();
	i2c_clear_sda();
	MY_DELAY_US(30);
	i2c_clear_scl();
}

/**-----------------------------------------------------------------------
  * @brief  主机向芯片发送restart指令
  * @param  无
  * @retval start标志位
-------------------------------------------------------------------------*/
void I2C_reStart(void)
{
	i2c_set_sda();
	MY_DELAY_US(1);  
	i2c_set_scl();
	MY_DELAY_US(1);  
	i2c_clear_sda();
	MY_DELAY_US(1); 
	i2c_clear_scl();
	MY_DELAY_US(1); 
}

/**-----------------------------------------------------------------------
  * @brief  主机向芯片发送stop指令
  * @param  无
  * @retval stop标志位
-------------------------------------------------------------------------*/
void I2C_Stop(void)
{  
	i2c_clear_sda();
	MY_DELAY_US(1);  
	i2c_set_scl();
	MY_DELAY_US(1);  
	i2c_set_sda();	
	MY_DELAY_US(1);
}

/**-----------------------------------------------------------------------
  * @brief  主机向芯片发送一个字节
  * @param  要发送的字节
  * @retval 是否应答
-------------------------------------------------------------------------*/
int I2C_master_write(uint8_t b)
{
  uint8_t mask = 0x80, ack;
	do
	{
		MY_DELAY_US(1); 
		sda_wr_control(b);	
		MY_DELAY_US(1); 	
		i2c_set_scl();
		MY_DELAY_US(1);  
		i2c_clear_scl();		
	}while ((mask>>=1) != 0);

	/* ACK slot checking */
	MY_DELAY_US(1);
	i2c_set_sda();
	MY_DELAY_US(1);
	i2c_set_scl();
	MY_DELAY_US(1); 
	ack = (i2c_get_sda()? 0:1);	
	MY_DELAY_US(1); 
	i2c_clear_scl();
	
	return (ack);
}

/**-----------------------------------------------------------------------
  * @brief  主机从芯片读取一个字节
  * @param  要发送给芯片的应答或非应答
  * @retval 读取到的一个字节数据
-------------------------------------------------------------------------*/
uint8_t I2C_master_read(uint8_t ack)
{ 
	uint8_t mask = 0x80, b = 0;
	i2c_set_sda();
	do
	{	
		MY_DELAY_US(1);	
		i2c_set_scl();
		MY_DELAY_US(1);
		sda_rd_control(b);
		i2c_clear_scl();
		MY_DELAY_US(1);
	}while ((mask>>=1) != 0);	
	/* ACK slot control */
	if(ack != 0)
	{
		i2c_clear_sda();		/* SDA=0 for ACK*/
	}
	else
	{
		i2c_set_sda();		/* SDA=1 for NACK*/
	}	
	MY_DELAY_US(1);
	i2c_set_scl();
	MY_DELAY_US(1);
	i2c_clear_scl();
	MY_DELAY_US(1);
	return (b);
}
